from decimal import Decimal

from django.db import transaction
from django.db.models import Q
from django.utils import timezone
from django_redis import get_redis_connection
from rest_framework import serializers

from apps.goods.models import SKU

# 商品结算
from apps.orders.models import OrderInfo, OrderGoods


class OrderPlaceSerializer(serializers.ModelSerializer):
    count = serializers.IntegerField(min_value=1, label="数量")

    class Meta:
        model = SKU
        fields = ("default_image_url", "name", "price", "count", "id")


# 订单结算
class OrderCommitSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderInfo
        fields = ("address", "pay_method", "order_id")

        # id只用于序列化用
        read_only_fields = ["order_id"]

        # 地址跟支付方式只用于反序列化
        extra_kwargs = {
            "address": {
                "write_only": True
            },
            "pay_method": {
                "write_only": True
            }
        }

    # 生成订单
    @transaction.atomic
    def create(self, validated_data):
        # 获取用户对象
        user = self.context["request"].user

        # 生成订单编号
        order_id = timezone.now().strftime("%Y%m%d%H%M%S") + "%06d" % user.id

        # 得到地址,订单
        address = validated_data.get("address")
        pay_method = validated_data.get("pay_method")

        # 判断支付方式
        if pay_method == OrderInfo.PAY_METHODS_ENUM["CASH"]:
            status = OrderInfo.ORDER_STATUS_ENUM["UNPAID"]
        else:
            status = OrderInfo.ORDER_STATUS_ENUM["UNSEND"]

        # 设置保存点
        sid = transaction.savepoint()

        # 先创建订单对象
        order = OrderInfo.objects.create(
            order_id=order_id,
            user=user,
            address=address,
            total_count=0,
            total_amount=Decimal(0.0),
            freight=Decimal(10.0),
            pay_method=pay_method,
            status=status,
        )

        # 获取redis对象
        redis_conn = get_redis_connection("cart")

        # 得到用户购买的商品列表
        sku_id_list = redis_conn.smembers("cart_selcted_%s" % user.id)

        for sku_id in sku_id_list:
            #获取该商品购买的数量
            sku_count = int(redis_conn.hget("cart_%s" % user.id,sku_id))

            #查看库存足够的商品总数
            sku=SKU.objects.filter(Q(id=sku_id),~Q(stock__lt=sku_count)).first()

            if sku:
                #修改商品库存与销量
                # sku.stock-=sku_count
                # sku.sales+=sku_count
                # sku.save()

                #得到新的库存跟新的销量
                new_stock = sku.stock - sku_count
                new_sales = sku.sales + sku_count

                #更新数据
                ret = SKU.objects.filter(Q(id=sku_id),~Q(stock__lt=sku_count)).update(stock=new_stock, sales=new_sales)

                #判断是否更新成功
                if ret == 0:
                    raise serializers.ValidationError("下单失败")


                #修改订单对象的数据跟价格
                order.total_count+=sku_count
                order.total_amount+=(sku.price*sku_count)


                #创建订单的商品对象
                OrderGoods.objects.create(
                    order=order,
                    sku=sku,
                    count=sku_count,
                    price=sku.price
                )
            else:
                # 回滚
                transaction.savepoint_rollback(sid)

                raise serializers.ValidationError("库存不足")

        #重新保存订单
        order.save()

        # 提交
        transaction.savepoint_commit(sid)

        #清除redis数据
        redis_conn.hdel("cart_%s" % user.id, *sku_id_list)
        redis_conn.srem("cart_selcted_%s" % user.id, *sku_id_list)

        return order





